//--------------------------------------------------------------
//
// Qizhi Zhang 
// ezhung@gmail.com
// http://www.moorwind.com
//
//--------------------------------------------------------------
package reader.view
{
	import __AS3__.vec.Vector;
	
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import mx.controls.Alert;
	
	import org.puremvc.as3.multicore.interfaces.IMediator;
	import org.puremvc.as3.multicore.interfaces.INotification;
	
	import reader.ApplicationFacade;
	import reader.core.IGCAble;
	import reader.core.ReaderModelLocator;
	import reader.core.ReaderResource;
	import reader.core.UserConfirmCommandConfig;
	import reader.events.BlogDraftEvent;
	import reader.model.IDraftProxy;
	import reader.model.IServiceProxy;
	import reader.model.vo.BlogDraftVO;
	import reader.services.IPostBlogAble;
	import reader.services.ServiceFactory;
	import reader.utils.StringUtils;
	import reader.view.components.BlogWriter;
	import reader.view.components.Writer;

	public class WriterMediator extends ServiceAbleMediator 
								implements IMediator, IGCAble
	{
		////////////////////////////////////////////////////////////////////////////////
		//public properties
		public static const NAME:String = "WriterMediator";
		
		public function get writer():Writer
		{
			return this.viewComponent as Writer;
		}
		
		////////////////////////////////////////////////////////////////////////////////
		//private variables
		private const SAVE_INTERVAL:uint = 1000;
		
		private var draftProxy:IDraftProxy;
		private var serviceProxy:IServiceProxy;
		
		private var isEditorInitialized:Boolean;
		private var editorDraft:BlogDraftVO;
		
		private var saveTimer:Timer;
		private var saveDownCounter:uint = 60;
		private var isSaveTimerOn:Boolean;
		private var autoSaving:String;
		private var autoSaved:String;
		
		private var isDisplayed:Boolean;
		private var postBlogService:IPostBlogAble;
		
		private var readerModelLocator:ReaderModelLocator = ReaderModelLocator.instance;
		
		//////////////////////////////////////////////////////////////////////////////
		//constructor
		public function WriterMediator(viewComponent:Object=null)
		{
			super(NAME, viewComponent);
			
			draftProxy = facade.retrieveProxy(readerModelLocator.sqliteProxyFactory.draftProxyName) as IDraftProxy;
			serviceProxy = facade.retrieveProxy(readerModelLocator.sqliteProxyFactory.serviceProxyName) as IServiceProxy;
			
			autoSaving = ReaderResource.instance.resource.blogWriterAutoSaveTimer;
			autoSaved = ReaderResource.instance.resource.blogWriterAutoSaved;
			
			writer.addEventListener(Writer.AUTO_SAVE, onAutoSave_handler, false, 0, true);
			writer.addEventListener(Writer.READ_AUTO_SAVED, onReadAutoSaved_handler, false, 0, true);
			writer.addEventListener(Writer.INSERT_PHOTOS, onInsertPhotos_handler, false, 0, true);
			writer.addEventListener(Writer.POST_BLOG, onPostBlog_handler, false, 0, true);
			writer.addEventListener(Writer.SAVE_DRAFT, onSaveDraft_handler, false, 0, true);
			writer.addEventListener(Writer.WRITER_INITIALIZED, onWriterInitialized_handler, false, 0, true);
			writer.addEventListener(BlogDraftEvent.OPEN_BLOG_DRAFT, onOpenForDraftDetail_handler, false, 0, true);
		}
		
		//////////////////////////////////////////////////////////////////////////////
		//methods
		
		override public function startUp():void
		{
			if(readerModelLocator.user.isAutoSave && !saveTimer)
			{
				saveTimer = new Timer(SAVE_INTERVAL);
				saveTimer.addEventListener(TimerEvent.TIMER, onSaveTimerTick_handler);
				saveTimer.start();
			}
			if(!writer.blogDrafts)
			{
				draftProxy.getUnPublishDraft(5);
			}
			isDisplayed = true;
		}
		
		override public function clearReference():void
		{
			if(saveTimer)
			{
				saveTimer.stop();
				saveTimer.removeEventListener(TimerEvent.TIMER, onSaveTimerTick_handler);
			}
			
			draftProxy = null;
			serviceProxy = null;
			autoSaving = null;
			autoSaved = null;
			readerModelLocator = null;
			writer.blogDrafts = null;
			
			writer.removeEventListener(Writer.INSERT_PHOTOS, onInsertPhotos_handler);
			writer.removeEventListener(Writer.POST_BLOG, onPostBlog_handler);
			writer.removeEventListener(Writer.SAVE_DRAFT, onSaveDraft_handler);
			writer.removeEventListener(Writer.AUTO_SAVE, onAutoSave_handler);
			writer.removeEventListener(Writer.READ_AUTO_SAVED, onReadAutoSaved_handler);
			writer.removeEventListener(BlogDraftEvent.OPEN_BLOG_DRAFT, onOpenForDraftDetail_handler);
			
			facade.removeMediator(NAME);
		}

		override public function listNotificationInterests():Vector.<String>
		{
			return Vector.<String>([ApplicationFacade.VIEW_START_UP,
									ApplicationFacade.INSERT_PHOTOS_HTML,									
									ApplicationFacade.WRITER_CLOSE,
									ApplicationFacade.AUTOSAVE_READ_OK,
									ApplicationFacade.EDIT_DRAFT,
									ApplicationFacade.WRITER_VIEW_CHANGE,
									ApplicationFacade.DRAFT_UNPUBED_OK,
									ApplicationFacade.DRAFT_PUBLISHED									
									]);
		}
		
		override public function handleNotification(notification:INotification):void
		{
			switch(notification.getName())
			{
				case ApplicationFacade.VIEW_START_UP:
					if(String(notification.getBody()) == BlogWriter.VIEW_NEW_BLOG)
					{
						startUp();
					}	
					break;
				case ApplicationFacade.INSERT_PHOTOS_HTML:
					writer.insertPhotoCodeToFCK(String(notification.getBody()));
					break;	
				case ApplicationFacade.WRITER_VIEW_CHANGE:
					if(String(notification.getBody()) == BlogWriter.VIEW_NEW_BLOG)
					{
						startUp();
					}
					else
					{
						isDisplayed = false;
					}					
					break;	
				case ApplicationFacade.WRITER_CLOSE:
					clearReference();
					break;		
				case ApplicationFacade.AUTOSAVE_READ_OK:
					resetAutoSave();
					var blogDraftVO:BlogDraftVO = notification.getBody() as BlogDraftVO;
					writer.blogTitle = blogDraftVO.title;
					writer.blogContent = blogDraftVO.description;
					break;
				case ApplicationFacade.DRAFT_UNPUBED_OK:
					if(writer)
						writer.blogDrafts = notification.getBody() as Vector.<BlogDraftVO>;
					break;
				case ApplicationFacade.DRAFT_PUBLISHED:
					if(isDisplayed)
						Alert.show(ReaderResource.instance.resource.blogWriterReadDraftPublished + notification.getType(), 
								ReaderResource.instance.resource.blogWriterReadDraftPublishedTitle, 4, writer);
					break;
				case ApplicationFacade.EDIT_DRAFT:
					if(isEditorInitialized)
					{
						var evt:BlogDraftEvent = new BlogDraftEvent(BlogDraftEvent.OPEN_BLOG_DRAFT, false, false, BlogDraftVO(notification.getBody()));
						onOpenForDraftDetail_handler(evt);
					}
					else
					{
						editorDraft = notification.getBody() as BlogDraftVO;
					}
					break;								
			}
		}
		
		//----------------------------------------------------------------------------
		//
		// Auto Save Timer Control Methods
		//
		//----------------------------------------------------------------------------
		
		private function startAutoSave():void
		{
			if(!readerModelLocator.user.isAutoSave)
			{
				sendNotification(ApplicationFacade.AUTOSAVE_CHANGE, true);
			}
			
			dePauseAutoSave();
		}
		
		private function stopAutoSave():void
		{
			if(readerModelLocator.user.isAutoSave)
			{
				sendNotification(ApplicationFacade.AUTOSAVE_CHANGE, false);				
			}
			pauseAutoSave();
		}
		
		private function pauseAutoSave():void
		{
			if(isSaveTimerOn)
			{
				isSaveTimerOn = false;
				saveTimer.stop();
			}
		}
		
		private function dePauseAutoSave():void
		{
			if(!isSaveTimerOn)
			{
				saveTimer.start();
				isSaveTimerOn = true;
			}
		}
		
		private function resetAutoSave():void
		{
			saveDownCounter = 60;
			startAutoSave();
		}
		
		//////////////////////////////////////////////////////////////////////////////
		//events
		
		private function onWriterInitialized_handler(e:Event):void
		{
			this.isEditorInitialized = true;
			if(editorDraft)
			{
				var evt:BlogDraftEvent = new BlogDraftEvent(BlogDraftEvent.OPEN_BLOG_DRAFT, false, false, editorDraft);
				onOpenForDraftDetail_handler(evt);
				editorDraft = null
			}
			
		}
		
		private function onInsertPhotos_handler(e:Event):void
		{
			sendNotification(ApplicationFacade.INSERT_PHOTOS);
		}
		
		private function onPostBlog_handler(e:Event):void
		{
			var blogDraftVO:BlogDraftVO = new BlogDraftVO();
			blogDraftVO.title = writer.blogTitle;
			blogDraftVO.description = writer.blogContent;
			postBlogService = ServiceFactory.getPostBlogService(writer.blogService, serviceProxy, draftProxy, writer, servicePool);
			postBlogService.newBlog(blogDraftVO);
		}
		
		//----------------------------------------------------------------------------
		//
		// open and edit an exits draft
		//
		//----------------------------------------------------------------------------
		
		
		private var tempDraft:BlogDraftVO;
		private function onOpenForDraftDetail_handler(e:BlogDraftEvent):void
		{
			if(StringUtils.removeExtraWhitespace(writer.blogContent) == "")
			{
				writer.blogTitle = e.draft.title;
				writer.blogContent = e.draft.description;
				writer.editDraft = e.draft;
			}
			else
			{
				tempDraft = e.draft;
				var uf:UserConfirmCommandConfig = new UserConfirmCommandConfig(ReaderResource.instance.resource.blogWriterReadSaved, 
					ReaderResource.instance.resource.blogWriterReadDraftAlert,
					writer, onDoReadDraftSaved_handler);
				sendNotification(ApplicationFacade.REQUEST_USERCONFIRM, uf);
			}
			
		}
		private function onDoReadDraftSaved_handler():void
		{
			writer.blogTitle = tempDraft.title;
			writer.blogContent = tempDraft.description;
			writer.editDraft = tempDraft;
			tempDraft = null;
		}
		
		private function onSaveDraft_handler(e:Event):void
		{
			var isEditDraft:Boolean = writer.editDraft && writer.editDraft.draftId > 0;
			var blogDraftVO:BlogDraftVO = isEditDraft ? writer.editDraft : new BlogDraftVO();
			var date:Date = new Date();
			
			blogDraftVO.title = StringUtils.removeExtraWhitespace(writer.blogTitle) == "" ? 
								ReaderResource.instance.resource.blogWriterUntitled + BlogDraftVO.formatDraftDate(date) : writer.blogTitle;
			blogDraftVO.description = writer.blogContent;
			blogDraftVO.creatDate = date;
			blogDraftVO.isPubed = false;
			
			if(isEditDraft) draftProxy.updateDraft(blogDraftVO);
			else draftProxy.saveDraft(blogDraftVO);			
		}
		
		//----------------------------------------------------------------------------
		//
		// Auto Save Timer Control Event Handlers
		//
		//----------------------------------------------------------------------------
		
		private function onAutoSave_handler(e:Event):void
		{
			resetAutoSave();
			var blogDraftVO:BlogDraftVO = new BlogDraftVO();
			blogDraftVO.title = writer.blogTitle;
			blogDraftVO.description = writer.blogContent;
			sendNotification(ApplicationFacade.AUTOSAVE_SAVE, blogDraftVO);
		}
		
		private function onReadAutoSaved_handler(e:Event):void
		{
			sendNotification(ApplicationFacade.AUTOSAVE_READ);
		}
		
		private function onSaveTimerTick_handler(e:TimerEvent):void
		{
			if(saveDownCounter > 0)
			{
				writer.autoSaveStatus.text = saveDownCounter + autoSaving;
				saveDownCounter --;				
			}
			else
			{
				saveDownCounter = 60;
				writer.autoSaveStatus.text = autoSaved;
				var blogDraftVO:BlogDraftVO = new BlogDraftVO();
				blogDraftVO.title = writer.blogTitle;
				blogDraftVO.description = writer.blogContent;
				sendNotification(ApplicationFacade.AUTOSAVE_SAVE, blogDraftVO);
			}
		}
		
	}
}